package spring_learn.a04;


import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.context.support.GenericApplicationContext;

/**
 * bean后处理器的作用
 */
@SpringBootApplication
public class A04 {
    /**
     * genericApplicaitonContext是一个干净的容器，不负责注解的解析
     * 通过添加bean的后处理器，才使得注解生效
     *
     * a. @Autowired 等注解的解析属于 bean 生命周期阶段(依赖注入, 初始化)的扩展功能
     * b. 这些扩展功能由 bean 后处理器来完成
     * @param args
     */
    public static void main(String[] args) {
        //这是一个 「干净」的applicationContext
        GenericApplicationContext genericApplicationContext=new GenericApplicationContext();
        genericApplicationContext.registerBean("bean1",Bean1.class);
        genericApplicationContext.registerBean("bean2",Bean2.class);
        genericApplicationContext.registerBean("bean3",Bean3.class);
        genericApplicationContext.registerBean("bean4",Bean4.class);
        genericApplicationContext.getDefaultListableBeanFactory().
                setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        //解析 autowried/value注解
        genericApplicationContext.registerBean(AutowiredAnnotationBeanPostProcessor.class);
        //解析resource /postConstruct/PreDestory注解
        genericApplicationContext.registerBean(CommonAnnotationBeanPostProcessor.class);
        //BeanPostProcessor to bind PropertySources to beans annotated with @ConfigurationProperties.
        ConfigurationPropertiesBindingPostProcessor.register(genericApplicationContext.getDefaultListableBeanFactory());
        String[] beanDefinitionNames = genericApplicationContext.getBeanDefinitionNames();
        for (String name:beanDefinitionNames)
            System.out.println(name);

        //初始化容器
        genericApplicationContext.refresh();// 执行beanFactory后处理器, 添加bean后处理器, 初始化所有单例
        //如果没加任何bean后处理器的话，这里显示的是 Bean1{bean2=null, bean3=null, home='null'}
        System.out.println(genericApplicationContext.getBean("bean1"));
        System.out.println(genericApplicationContext.getBean("bean2"));
        System.out.println(genericApplicationContext.getBean("bean4"));
        //销毁容器
        genericApplicationContext.close();
    }
}
